package cn.xawl.interview.thread;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author lh
 * @date 2020/08/26 20:57:22
 *
 * 传统版生产者消费者模型：线程操作资源类，判断-干活-通知。*防止虚假唤醒（使用while循环判断，if判断：如果同时唤醒多个准备消费或者生产的线程，由于if已经判断过，多个线程一次获取锁，消费或者生产 会导致虚假唤醒）
 * 一个初始值为0的变量，两个线程交替操作，一个加一，一个减一。来五轮
 **/
public class ProductConsumerDemo01 {

    public static void main(String[] args) {
        ShareVar shareVar = new ShareVar();

        for (int i = 1; i <= 3; i++) {
            new Thread(shareVar::increment, "AA").start();
        }
        for (int i = 1; i <= 3; i++) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(shareVar::decrement, "BB").start();
        }
    }

}


class ShareVar {
    private int num = 0;
    private final Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    public void increment() {
        lock.lock();
        try {
            //判断
            while (num != 0) {//不为0停止生产
                condition.await();
            }
            //干活
            num++;
            System.out.println(Thread.currentThread().getName() + "\t" + num);
            //通知
            condition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void decrement() {
        lock.lock();
        try {
            //判断
            while (num == 0) {//为0时停止消费
                condition.await();
            }
            //干活
            num--;
            System.out.println(Thread.currentThread().getName() + "\t" + num);
            //通知
            condition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}